// The libMesh Finite Element Library.
// Copyright (C) 2002-2018 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


// Local Includes
#include "libmesh/libmesh_config.h"
#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
#include "libmesh/inf_fe.h"

namespace libMesh
{

// Anonymous namespace for local helper functions
namespace {

Real jacobi_20_00_eval(Real v, unsigned i)
{
  libmesh_assert (-1.-1.e-5 <= v && v < 1.);

  switch (i)
    {
    case 0:
      return 1.;

    case 1:
      return 2.+2.*v;

    case 2:
      return -1.25+
        (2.5+3.75*v)*v;

    case 3:
      return .25+
        (-1.5+
         (5.25+7.*v)*v)*v;

    case 4:
      return -.875+
        (-3.5+
         (-5.25+
          (10.5+13.125*v)*v)*v)*v;

    case 5:
      return 1.625+
        (1.25+
         (-11.25+
          (-15.+
           (20.625+24.75*v)*v)*v)*v)*v;

    case 6:
      return -1.078125+(4.21875+
                        (6.328125+
                         (-30.9375+
                          (-38.671875+
                           (40.21875+46.921875*v)*v)*v)*v)*v)*v;

    case 7:
      return .453125+(-1.09375+
                      (18.046875+
                       (24.0625+
                        (-78.203125+
                         (-93.84375+
                          (78.203125+89.375*v)*v)*v)*v)*v)*v)*v;

    case 8:
      return -.9453125+(-4.8125+
                        (-7.21875+
                         (62.5625+
                          (78.203125+
                           (-187.6875+
                            (-218.96875+
                             (151.9375+170.9296875*v)*v)*v)*v)*v)*v)*v)*v;

    case 9:
      return 1.4921875+(.984375+
                        (-25.59375+
                         (-34.125+
                          (191.953125+
                           (230.34375+
                            (-435.09375+
                             (-497.25+
                              (295.2421875+328.046875*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 10:
      return -1.041015625+(5.33203125+
                           (7.998046875+
                            (-106.640625+
                             (-133.30078125+
                              (543.8671875+
                               (634.51171875+
                                (-984.140625+
                                 (-1107.158203125+
                                  (574.08203125+631.490234375*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 11:
      return .548828125+(-.90234375+
                         (33.837890625+
                          (45.1171875+
                           (-383.49609375+
                            (-460.1953125+
                             (1457.28515625+
                              (1665.46875+
                               (-2185.927734375+
                                (-2428.80859375+
                                 (1117.251953125+1218.8203125*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 12:
      return -.9677734375+
        (-5.80078125+
         (-8.701171875+
          (164.35546875+
           (205.4443359375+
            (-1249.1015625+
             (-1457.28515625+
              (3747.3046875+
               (4215.7177734375+
                (-4788.22265625+
                 (-5267.044921875+
                  (2176.46484375+2357.8369140625*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 13:
      return 1.418945312499432+
        (.837890625+
         (-42.732421875+
          (-56.9765625+
           (676.5966796875+
            (811.9160156249999+
             (-3788.94140625+
              (-4330.21875+
               (9337.0341796875+
                (10374.482421875+
                 (-10374.482421875+
                  (-11317.6171875+
                   (4244.1064453125+4570.576171875*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 14:
      return -1.02618408203125+
        (6.2318115234375+
         (9.34771728515625+
          (-236.808837890625+
           (-296.0110473632813+
            (2486.492797851563+
             (2900.908264160156+
              (-10893.20654296875+
               (-12254.85736083984+
                (22694.18029785156+
                 (24963.59832763672+
                  (-22281.55883789063+
                   (-24138.35540771484+
                    (8284.169311523438+8875.895690917969*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 15:
      return .60723876953125+
        (-.7855224609375+
         (52.23724365234375+
          (69.649658203125+
           (-1096.982116699219+
            (-1316.378540039063+
             (8410.196228027344+
              (9611.65283203125+
               (-30036.41510009766+
                (-33373.79455566406+
                 (54065.54718017578+
                  (58980.59692382813+
                   (-47512.14752197266+
                    (-51166.92810058594+
                     (16185.45684814453+17264.4873046875*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 16:
      return -.978179931640625+
        (-6.63330078125+
         (-9.949951171875+
          (325.03173828125+
           (406.2896728515625+
            (-4485.43798828125+
             (-5233.010986328125+
              (26699.03564453125+
               (30036.41510009766+
                (-80097.10693359375+
                 (-88106.81762695313+
                  (126699.0600585938+
                   (137257.3150634766+
                    (-100709.5092773438+
                     (-107903.0456542969+
                      (31651.56005859375+33629.78256225586*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 17:
      return 1.370941162109141+
        (.74188232421875+
         (-62.31811523437499+
          (-83.0908203125+
           (1672.202758789063+
            (2006.643310546875+
             (-16722.02758789063+
              (-19110.888671875+
               (80624.06158447266+
                (89582.29064941406+
                 (-207830.9143066406+
                  (-226724.6337890625+
                   (292852.6519775391+
                    (315379.7790527344+
                     (-212398.6267089844+
                      (-226558.53515625+
                       (61949.5994567871+65593.69354248047*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 18:
      return -1.018547058106322+
        (7.010787963867187+
         (10.51618194580078+
          (-429.9949951171874+
           (-537.4937438964844+
            (7524.91241455078+
             (8779.064483642578+
              (-58049.32434082031+
               (-65305.48988342284+
                (233809.7785949707+
                 (257190.7564544677+
                  (-527134.7735595703+
                   (-571062.6713562012+
                    (669055.6741333008+
                     (716845.3651428223+
                      (-446037.1160888671+
                       (-473914.4358444213+
                        (121348.3330535889+128089.9071121216*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;


    default:
      libmesh_error_msg("bad index i = " << i);
    }
} // jacobi_20_00_eval()





Real jacobi_20_00_eval_deriv(Real v, unsigned i)
{
  libmesh_assert (-1.-1.e-5 <= v && v < 1.);

  switch (i)
    {
    case 0:
      return 0.;

    case 1:
      return 2.;

    case 2:
      return 7.5*v+2.5;

    case 3:
      return -1.5+
        (10.5+21.*v)*v;

    case 4:
      return -3.5+
        (-10.5+
         (31.5+52.5*v)*v)*v;

    case 5:
      return 1.25+
        (-22.5+
         (-45.+
          (82.5+123.75*v)*v)*v)*v;

    case 6:
      return 4.21875+
        (12.65625+
         (-92.8125+
          (-154.6875+
           (201.09375+281.53125*v)*v)*v)*v)*v;

    case 7:
      return -1.09375+
        (36.09375+
         (72.1875+
          (-312.8125+
           (-469.21875+
            (469.21875+625.625*v)*v)*v)*v)*v)*v;

    case 8:
      return -4.8125+
        (-14.4375+
         (187.6875+
          (312.8125+
           (-938.4375+
            (-1313.8125+
             (1063.5625+1367.4375*v)*v)*v)*v)*v)*v)*v;

    case 9:
      return .984375+
        (-51.1875+
         (-102.375+
          (767.8125+
           (1151.71875+
            (-2610.5625+
             (-3480.75+
              (2361.9375+2952.421875*v)*v)*v)*v)*v)*v)*v)*v;

    case 10:
      return 5.33203125+
        (15.99609375+
         (-319.921875+
          (-533.203125+
           (2719.3359375+
            (3807.0703125+
             (-6888.984375+
              (-8857.265625+
               (5166.73828125+6314.90234375*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 11:
      return -.90234375+
        (67.67578125+
         (135.3515625+
          (-1533.984375+
           (-2300.9765625+
            (8743.7109375+
             (11658.28125+
              (-17487.421875+
               (-21859.27734375+
                (11172.51953125+13407.0234375*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 12:
      return -5.80078125+
        (-17.40234375+
         (493.06640625+
          (821.77734375+
           (-6245.5078125+
            (-8743.7109375+
             (26231.1328125+
              (33725.7421875+
               (-43094.00390625+
                (-52670.44921875+
                 (23941.11328125+28294.04296875*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 13:
      return .837890625+
        (-85.46484375+
         (-170.9296875+
          (2706.38671875+
           (4059.580078124999+
            (-22733.6484375+
             (-30311.53125+
              (74696.2734375+
               (93370.341796875+
                (-103744.82421875+
                 (-124493.7890625+
                  (50929.27734375+59417.490234375*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 14:
      return 6.2318115234375+
        (18.6954345703125+
         (-710.426513671875+
          (-1184.044189453125+
           (12432.46398925781+
            (17405.44958496094+
             (-76252.44580078125+
              (-98038.85888671875+
               (204247.6226806641+
                (249635.9832763672+
                 (-245097.1472167969+
                  (-289660.2648925781+
                   (107694.2010498047+124262.5396728516*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 15:
      return -.7855224609375+
        (104.4744873046875+
         (208.948974609375+
          (-4387.928466796875+
           (-6581.892700195313+
            (50461.17736816406+
             (67281.56982421875+
              (-240291.3208007813+
               (-300364.1510009766+
                (540655.4718017578+
                 (648786.5661621094+
                  (-570145.7702636719+
                   (-665170.0653076172+
                    (226596.3958740234+258967.3095703125*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 16:
      return -6.63330078125+
        (-19.89990234375+
         (975.09521484375+
          (1625.15869140625+
           (-22427.18994140625+
            (-31398.06591796875+
             (186893.2495117188+
              (240291.3208007813+
               (-720873.9624023438+
                (-881068.1762695313+
                 (1393689.660644531+
                  (1647087.780761719+
                   (-1309223.620605469+
                    (-1510642.639160156+
                     (474773.4008789063+538076.5209960938*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 17:
      return .74188232421875+
        (-124.63623046875+
         (-249.2724609375+
          (6688.81103515625+
           (10033.21655273437+
            (-100332.1655273438+
             (-133776.220703125+
              (644992.4926757813+
               (806240.6158447266+
                (-2078309.143066406+
                 (-2493970.971679688+
                  (3514231.823730469+
                   (4099937.127685547+
                    (-2973580.773925781+
                     (-3398378.02734375+
                      (991193.5913085936+1115092.790222168*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 18:
      return 7.010787963867187+
        (21.03236389160156+
         (-1289.984985351562+
          (-2149.974975585938+
           (37624.5620727539+
            (52674.38690185547+
             (-406345.2703857421+
              (-522443.9190673828+
               (2104288.007354736+
                (2571907.564544677+
                 (-5798482.509155273+
                  (-6852752.056274414+
                   (8697723.76373291+
                    (10035835.11199951+
                     (-6690556.741333007+
                      (-7582630.973510741+
                       (2062921.66191101+2305618.328018188*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;


    default:
      libmesh_error_msg("bad index i = " << i);
    }
} // jacobi_20_00_eval_deriv()


} // anonymous namespace



  // Specialize the eval() function for 1, 2, and 3 dimensions and the CARTESIAN mapping type
  // to call the local helper function from the anonymous namespace.
template <> Real InfFE<1,JACOBI_20_00,CARTESIAN>::eval(Real v, Order, unsigned i) { return jacobi_20_00_eval(v, i); }
template <> Real InfFE<2,JACOBI_20_00,CARTESIAN>::eval(Real v, Order, unsigned i) { return jacobi_20_00_eval(v, i); }
template <> Real InfFE<3,JACOBI_20_00,CARTESIAN>::eval(Real v, Order, unsigned i) { return jacobi_20_00_eval(v, i); }

// Specialize the eval_deriv() function for 1, 2, and 3 dimensions and the CARTESIAN mapping type
// to call the local helper function from the anonymous namespace.
template <> Real InfFE<1,JACOBI_20_00,CARTESIAN>::eval_deriv(Real v, Order, unsigned i) { return jacobi_20_00_eval_deriv(v, i); }
template <> Real InfFE<2,JACOBI_20_00,CARTESIAN>::eval_deriv(Real v, Order, unsigned i) { return jacobi_20_00_eval_deriv(v, i); }
template <> Real InfFE<3,JACOBI_20_00,CARTESIAN>::eval_deriv(Real v, Order, unsigned i) { return jacobi_20_00_eval_deriv(v, i); }

} // namespace libMesh

#endif // LIBMESH_ENABLE_INFINITE_ELEMENTS
